/**
 * Project: TacticaPescaditos
 * File: Ball.java
 */
package org.javahispano.javacup.tacticas_aceptadas.Pescaditos.com.chidotronics.javacup;


import java.awt.geom.Line2D;

import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.SituacionPartido;

import org.javahispano.javacup.tacticas_aceptadas.Pescaditos.com.chidotronics.javacup.geometrics.Segment2D;
import org.javahispano.javacup.tacticas_aceptadas.Pescaditos.com.chidotronics.javacup.geometrics.Vector2D;

/**
 * @author Carlos Alberto
 * class: Ball
 */
public class Ball {
	
	public static final double FRICTION = ( Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE + Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO)/2 -1;

	private static final double AIR_FRICTION = Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE -1 ;



	private static final double G =  -Constantes.G ;

	static final double GROUND_FRICTION = Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO -1 ;

	

	
	
	/**
	 * 
	 */
	public Ball() {


		setVelocityZero();
	}

	private double z;
	
	private double speedZ;	

	private Vector2D position;
	private Vector2D velocity;
	private double speed;
	
	private Vector2D predictedPosition;
	
	
	



	public Vector2D getPosition() {
		return position;
	}

	public double getSpeed() {
		return speed;
	}
	
	private Segment2D trajectory;
	
	
	
	private void setVelocityZero(){
		position = new Vector2D();
		velocity = new Vector2D();
		this.speed = this.speedZ = 0;
		this.velocity = new Vector2D();
		this.predictedPosition = this.position;
		trajectory = new Segment2D();
	}
    public static double redondeaMultiplo(double valor, double divisor) {
        return Math.round(valor / divisor) * divisor;
    }
    public void predictPosition(){





    	this.predictedPosition = calculateFuturePosition(100);
    	this.trajectory = new Segment2D( this.position,this.predictedPosition);


    }

	public Vector2D calculateFuturePosition(int time) {
		
    	double dz = this.z ;
    	double dr = this.speed;
    	double r=0;
    	double z =0;
    	boolean suelo = false;
    	for (int i = 0; i < time; i++) {

    		if (!suelo && z == 0 && dz < Constantes.G * 3) {//condicion para que se arrastre
    			suelo = true;
    		}
    		if (suelo) {
    			r = r + dr;
    			dr = dr * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
    		} else {
    			z = redondeaMultiplo(z + dz, Constantes.G);
    			r = r + dr;
    			dz = redondeaMultiplo(dz - Constantes.G, Constantes.G);
    			dr = dr * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
    			if (z == 0) {
    				dz = (-dz - Constantes.G) * Constantes.FACTOR_DISMINUCION_ALTURA_BALON_REBOTE;
    				dz = redondeaMultiplo(dz, Constantes.G);

    			}
    		}
    	}
    	
    	return this.position.add( this.velocity.normalized().multiply((r-this.speed)) );

	}


	public void update(SituacionPartido sp) {
		double z = sp.alturaBalon();
		this.speedZ = z - this.z;
		this.z = z;

		Posicion posicion = sp.balon();
		Vector2D newPos = new Vector2D(posicion .getX(), posicion.getY());
		this.velocity = newPos.substract(this.position);
		this.speed = this.velocity.length();
		this.position=newPos;
	}

	public double timeToCoverDistance(Vector2D posA,
            Vector2D posB,
            double speed, double angleV) {
		
		
		double dz = Ball.redondeaMultiplo(speed * Math.sin(angleV), Constantes.G); ;
		double dr = speed;
		double r= posA.distance(posB);
		double z =0;
		boolean suelo = false;
		int time;
        for ( time = 0; time < 100 && r>0; time++) {

            if (!suelo && z == 0 && dz < Constantes.G * 3) {//condicion para que se arrastre
                suelo = true;
            }
            if (suelo) {
                r -= dr;
                dr = dr * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            } else {
                z = redondeaMultiplo(z + dz, Constantes.G);
                r -=  dr;
                dz = redondeaMultiplo(dz - Constantes.G, Constantes.G);
                dr = dr * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
                if (z == 0) {
                    dz = (-dz - Constantes.G) * Constantes.FACTOR_DISMINUCION_ALTURA_BALON_REBOTE;
                    dz = redondeaMultiplo(dz, Constantes.G);
      
                }
            }
}

		  return time;
	}





	public double getHeight() {
		return this.z;
	}

	public Vector2D getVelocity() {		
		return velocity;
	}

	/**
	 * @return the speedZ
	 */
	public double getSpeedZ() {
		return speedZ;
	}

	public Vector2D getPredictedPosition() {
		return this.predictedPosition;
	}

	/**
	 * @return the trajectory
	 */
	public Segment2D getTrajectory() {
		return trajectory;
	}





	

}
